package com.slanmao.controller;

import com.slanmao.aes.AesException;
import com.slanmao.common.entity.InputMessage;
import com.slanmao.common.entity.Response;
import com.slanmao.common.utils.HttpUtils;
import com.slanmao.common.utils.LocationUtils;
import com.slanmao.common.utils.SerializeXmlUtil;
import com.slanmao.common.utils.TokenUtils;
import com.slanmao.entity.Reply;
import com.slanmao.entity.UserInfo;
import com.slanmao.exception.CommonException;
import com.slanmao.service.AreaServService;
import com.slanmao.service.MsgService;
import com.slanmao.service.ReplyService;
import com.slanmao.service.UserService;
import com.thoughtworks.xstream.XStream;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.slanmao.controller.MessageHandler.*;


/**
 * <CODE>ReplyController</CODE>
 * 自动回复处理器
 * @author fenrir
 * @Date 18-12-5
 */

@Controller
@Slf4j
public class ReplyController {


    public static final String token = "comeback";

    public static final String encodingAesKey = "bef1a3e7c96543Ee839f3974a8569adcfed39EFabc5";

    public static final String appId = "wxe7d249b30b01bf45";

    @Autowired
    AreaServService areaServService;

    @Autowired
    UserService userService;

    @Autowired
    ReplyService replyService;

    @Autowired
    HttpUtils httpUtils;

    @Autowired
    TokenUtils tokenUtils;

    @Autowired
    MsgService msgService;

    @Autowired
    LocationUtils locationUtil;

    @Value("${server.location}")
    private String serverLocation;


    @RequestMapping("/index")
    public String index(Model model){
        model.addAttribute("serverLocation",serverLocation);
        return "index";
    }

    @RequestMapping("/form")
    public String form(Model model){
        model.addAttribute("serverLocation",serverLocation);
        return "form";
    }



    @RequestMapping("/msg")
    public @ResponseBody
    String checkValidate(HttpServletRequest request) throws AesException {
        String queryString = request.getQueryString();
        log.info("接受消息推送,请求参数:"+queryString);
        boolean isGet = request.getMethod().toLowerCase().equals("get");
        if (isGet) {
            return acceptGet(request);
        } else {
            // 进入POST聊天处理
            log.info("enter post");
            try {
                // 接收消息并返回消息
                return acceptPost(request);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "success";
    }

    @GetMapping("/list")
    public @ResponseBody
    Response checkValidate(@RequestParam("page")int start, @RequestParam("limit")int size) throws AesException {
        Map<String,Integer> param = new HashMap<>();
        param.put("start",start>0?start-1:0);
        param.put("size",size);
        List<Reply> list = replyService.list(param);
        Integer count = replyService.count();
        Response response = new Response();
        response.setCode(200);
        response.setTotal(count);
        response.setData(list);
        return response;
    }

    @PostMapping("/update")
    public @ResponseBody Response update(@RequestBody Reply reply){
        replyService.updateReply(reply);
        return new Response();
    }

    @PostMapping("/save")
    public @ResponseBody Response save(@RequestBody Reply reply){
        replyService.insert(reply);
        return new Response();
    }

    @GetMapping("/delete")
    public @ResponseBody Response delete(@RequestParam("id")Integer id){
        replyService.delete(id);
        return new Response();
    }

    public String acceptGet(HttpServletRequest request){
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        log.info("signature:"+signature);
        log.info("timestamp:"+timestamp);
        log.info("nonce:"+nonce);
        log.info("echostr:"+echostr);
        //sha1加密
        Boolean result = verifyInfo(signature, timestamp, nonce,token);
        log.info("解密结果:"+result);
//        log.info("解密字符串为" + temp);
//        log.info("signature为" + signature);
        if (result) {
            log.info("成功");
            return echostr;
        }
        log.info("失败");
        return null;
    }

    public String acceptPost(HttpServletRequest request) throws IOException {
        //回复类型
        int replyType = 0;
        // 处理接收消息
        ServletInputStream in = request.getInputStream();
        // 将POST流转换为XStream对象
        XStream xs = SerializeXmlUtil.createXstream();
        xs.processAnnotations(InputMessage.class);
        // 将指定节点下的xml节点数据映射为对象
        xs.alias("xml", InputMessage.class);
        // 将流转换为字符串
        StringBuilder xmlMsg = new StringBuilder();
        byte[] b = new byte[4096];
        for (int n; (n = in.read(b)) != -1;) {
            xmlMsg.append(new String(b, 0, n, "UTF-8"));
        }
        // 将xml内容转换为InputMessage对象
        InputMessage inputMsg = (InputMessage) xs.fromXML(xmlMsg.toString());
        log.info("消息内容"+inputMsg.toString());

        //存到数据库
        try {
            //如果是微信地理位置上报接口,调用高德API获取中文地址
            if (inputMsg.getEvent()!=null&&inputMsg.getEvent().equals("LOCATION")){
                String address = locationUtil.convert(inputMsg.getLongitude(), inputMsg.getLatitude());
                inputMsg.setFormat_location(address);
            }

            String fromUserName = inputMsg.getFromUserName();
            UserInfo byOpenId = userService.findByOpenId(fromUserName);
            if (byOpenId==null){
                userService.insert(byOpenId);
            }
            msgService.insert(inputMsg);
        }catch (Exception e){
            log.info("保存消息异常",e);

        }

        // 取得消息类型
        String msgType = inputMsg.getMsgType();
        // 根据消息类型获取对应的消息内容

        switch (msgType){

            case "text":
                return handleText(replyType, inputMsg);

            case "image":
                return handleImage(inputMsg);

            case "event":

                return handlerEvent(inputMsg);

        }

       return "success";
    }


    /**
     * 输出工单的微信二维码
     * @param id 工单ID
     */
    @RequestMapping(value = "/getQRurl")
    public @ResponseBody Response getImage(@RequestParam("id")String id) {
        try {
            String accessToken = tokenUtils.getAccessToken();
            return new Response<>(httpUtils.getQRImage(id, accessToken));
        } catch (CommonException e) {
            log.info("发生错误:"+e.getMessage());
            return new Response(e);
        }
    }


    @GetMapping("/listMsg")
    public @ResponseBody
    Response listMsg(@RequestParam("page")int start, @RequestParam("limit")int size) {
        List<InputMessage> list = msgService.list(start, size);
        Integer count = msgService.count();
        Response response = new Response();
        response.setCode(200);
        response.setTotal(count);
        response.setData(list);
        return response;
    }




}
